06. 类文件结构

头文件

在前面的例子中,你看到了如何将一个类分成一个独立于 main.cpp 的文件(gaussian.cpp)。但是,主程序文件和 gaussian 类文件都需要在代码顶部进行完全相同的类声明:

//类声明
class Gaussian
{
    private:
        float mu, sigma2;

    public:

        //构造函数
        Gaussian ();
        Gaussian (float, float);

        //改变均差和标准偏差的值 
        void setMu(float);
        void setSigma2(float);

        //输出均差和标准偏差的值
        float getMu();
        float getSigma2();

        //待评估函数 
        float evaluate (float);
        Gaussian mul (Gaussian);
        Gaussian add (Gaussian);
};

不需要写两次声明,只需要将声明写入头文件即可。然后,你可以用一行代码包含整个声明:

Start Quiz:

#include <iostream>
#include "gaussian.h"

int main ()
{

	Gaussian mygaussian(30.0,20.0);
	Gaussian othergaussian(10.0,30.0);
	
	std::cout << "average " << mygaussian.getMu() << std::endl;
	std::cout << "evaluation " << mygaussian.evaluate(15.0) << std::endl;

	std::cout << "mul results sigma " << mygaussian.mul(othergaussian).getSigma2() << std::endl;
	std::cout << "mul results average " << mygaussian.mul(othergaussian).getMu() << std::endl;

	std::cout << "add results sigma " << mygaussian.add(othergaussian).getSigma2() << std::endl;
	std::cout << "add results average " << mygaussian.add(othergaussian).getMu() << std::endl;

	return 0;
}
#include <math.h>       /* sqrt, exp */
#include "gaussian.h"

Gaussian::Gaussian() {
	mu = 0;
	sigma2 = 1;	
}

Gaussian::Gaussian (float average, float sigma) {
	mu = average;
	sigma2 = sigma;
}

void Gaussian::setMu (float average) {
	mu = average;
}

void Gaussian::setSigma2 (float sigma) {
	sigma2 = sigma;
}


float Gaussian::getMu () {
	return mu;
}

float Gaussian::getSigma2() {
	return sigma2;
}

float Gaussian::evaluate(float x) {
	float coefficient;
	float exponential;

	coefficient = 1.0 / sqrt (2.0 * M_PI * sigma2);
	exponential = exp ( pow (-0.5 * (x - mu), 2) / sigma2 );
	return coefficient * exponential;
}

Gaussian Gaussian::mul(Gaussian other) {
	float denominator;
	float numerator;
	float new_mu;
	float new_var;

	denominator = sigma2 + other.getSigma2();
	numerator = mu * other.getSigma2() + other.getMu() * sigma2;
	new_mu = numerator / denominator;

	new_var = 1.0 / ( (1.0 / sigma2) + (1.0 / other.sigma2) );

	return Gaussian(new_mu, new_var);
}

Gaussian Gaussian::add(Gaussian other) {

	float new_mu;
	float new_sigma2;

	new_mu = mu + other.getMu();
	new_sigma2 = sigma2 + other.getSigma2();

	return Gaussian(new_mu, new_sigma2);
}
class Gaussian
{
	private:
		float mu, sigma2;

	public:
		
		// constructor functions
		Gaussian ();
		Gaussian (float, float);

		// change value of average and standard deviation 
		void setMu(float);
		void setSigma2(float);

		// output value of average and standard deviation
		float getMu();
		float getSigma2();

		// functions to evaluate 
		float evaluate (float);
		Gaussian mul (Gaussian);
		Gaussian add (Gaussian);
};

头文件中发生了什么?

在上一课中介绍了头文件。头文件允许你把函数声明放在一个单独的文件中。这样,使用并包含头文件即可更轻松地在程序的不同部分重用函数。此外,如果类声明改变,你只需要在一个地方更改声明。

对于类而言,头文件的功能完全相同。当你在 main.cpp 中使用 Gaussian 类的时候,你只需头文件中包括头文件即可,即在顶部输入代码 include "gaussian.h" 。这样, main.cpp 就可以访问 Gaussian 类。

同样,对于 gaussian.cpp,你也可以包含头文件,而无需写出整个声明。

在头文件中使用 include

一般而言,我们建议将所需的最小数量的 # include (包含 #include "" #include <> 两种方式)语句放入头文件中。但是,因为头文件实际上会被复制到 .cpp 文件中,所以你可能会无意中多次 include 相同的库或文件。这样的结果是,变量、函数或类可能被多次声明,代码将不会被编译。在本课的下一部分中,你将了解到元素被多次声明时会发生什么,你还将学习如何避免多重声明。